package com.bsoft.gol.hcs.specialist.service.impl;

import ctd.controller.exception.ControllerException;
import ctd.persistence.annotation.DAOTransaction;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.annotation.RpcService;
import com.bsoft.gol.hcs.enumcase.RuleConditionTypeEnum;
import com.bsoft.gol.hcs.enumcase.SubscribeModeEnum;
import hcn.util.BaseResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.bsoft.gol.hcs.specialist.bean.request.PatientSearchRuleRequest;
import com.bsoft.gol.hcs.specialist.bean.request.SaveOrSearchRequest;
import com.bsoft.gol.hcs.specialist.bean.response.GetDetailResponse;
import com.bsoft.gol.hcs.specialist.bean.response.ListPatientSearchRuleResponse;
import com.bsoft.gol.hcs.specialist.bean.response.ListSubscribeResponse;
import com.bsoft.gol.hcs.specialist.bean.response.SaveOrSearchResponse;
import com.bsoft.gol.hcs.specialist.dao.PatientSearchRuleDAO;
import com.bsoft.gol.hcs.specialist.dao.PatientSearchRuleDetailDAO;
import com.bsoft.gol.hcs.specialist.dao.PatientSearchRuleSubscribeDAO;
import com.bsoft.gol.hcs.specialist.entity.PatientSearchRule;
import com.bsoft.gol.hcs.specialist.entity.PatientSearchRuleDetail;
import com.bsoft.gol.hcs.specialist.entity.PatientSearchRuleSubscribe;
import com.bsoft.gol.hcs.specialist.service.IPatientSearchRuleExecuteService;
import com.bsoft.gol.hcs.specialist.service.PrsSearchRuleService;
import com.bsoft.gol.hcs.utils.CommonUtils;
import com.bsoft.gol.hcs.utils.DateUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 提供高级检索、检索规则 订阅 服务层
 *
 * @author lixy
 * @date 2021/8/8 15:22
 */
@SsdevService("prsSearchRule")
public class PrsSearchRuleServiceImpl implements PrsSearchRuleService {


    @Autowired
    private PatientSearchRuleDAO patientSearchRuleDAO;

    @Autowired
    private PatientSearchRuleDetailDAO patientSearchRuleDetailDAO;

    @Autowired
    private PatientSearchRuleSubscribeDAO patientSearchRuleSubscribeDAO;

    @Resource(name = "patientSearchRuleExecuteService")
    private IPatientSearchRuleExecuteService patientSearchRuleExecuteService;


    @Override
    @RpcService
    public List<ListPatientSearchRuleResponse> listPatientSearchRule(PatientSearchRuleRequest request) throws ControllerException {
        if (CommonUtils.isEmpty(request.getUserId())) {
            throw new ControllerException("用户ID不可为空");
        }
        return patientSearchRuleDAO.queryPatientSearchRuleByUserId(request.getUserId());
    }

    @Override
    @RpcService
    public Map<String, Object> listHistoryPatientSearchRule(PatientSearchRuleRequest request) throws ControllerException {
        if (CommonUtils.isEmpty(request.getUserId())) {
            throw new ControllerException("用户ID不可为空");
        }
        if (CommonUtils.isEmpty(request.getPageNo()) || CommonUtils.isEmpty(request.getPageSize())) {
            throw new ControllerException("分页参数不可为空");
        }
        List<ListPatientSearchRuleResponse> listPatientList = null;
        //获取历史检索总数
        Long total = patientSearchRuleDAO.queryHistoryPatientSearchRuleCount(request.getUserId());
        if (total > 0) {
            listPatientList = patientSearchRuleDAO.queryHistoryPatientSearchRuleByUserId(request.getUserId(), request.getPageNo(), request.getPageSize());
        } else {
            total = 0L;
            listPatientList = new ArrayList<>();
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("total", total);
        resultMap.put("data", listPatientList);
        return resultMap;
    }

    @Override
    @RpcService
    public void updateSubscribeStatus(PatientSearchRuleRequest request) throws ControllerException {
        if (CommonUtils.isEmpty(request.getUserId())) {
            throw new ControllerException("用户ID不可为空");
        }
        if (CommonUtils.isEmpty(request.getPatientSearchRuleId())) {
            throw new ControllerException("检索规则id不可为空");
        }
        String userId = request.getUserId();
        Long patientSearchRuleId = request.getPatientSearchRuleId();
        Byte isSubscribe = request.getIsSubscribe();
        if (CommonUtils.isEmpty(isSubscribe)) {
            throw new ControllerException("参数isSubscribe不能为空");
        }
        //订阅
        if (SubscribeModeEnum.SUBSCRIBE.getModeCode().compareTo(isSubscribe) == 0) {
            PatientSearchRuleSubscribe subscribe = patientSearchRuleSubscribeDAO.getByUserIdAndPatientSearchRuleId(userId, patientSearchRuleId);
            if (CommonUtils.isEmpty(subscribe)) {
                PatientSearchRuleSubscribe subscribe1 = new PatientSearchRuleSubscribe();
                subscribe1.setPatientSearchRuleId(patientSearchRuleId);
                subscribe1.setUserId(userId);
                patientSearchRuleSubscribeDAO.save(subscribe1);
            }
            return;
        }
        //取消订阅
        if (SubscribeModeEnum.UN_SUBSCRIBE.getModeCode().compareTo(isSubscribe) == 0) {
            patientSearchRuleSubscribeDAO.deleteByUserIdAndPatientSearchRuleId(userId, patientSearchRuleId);
            return;
        }
        throw new ControllerException("参数isSubscribe不能为空");
    }

    @Override
    @RpcService
    public GetDetailResponse getDetail(Long patientSearchRuleId) throws ControllerException {
        if (CommonUtils.isEmpty(patientSearchRuleId)) {
            throw new ControllerException("检索规则id不可为空");
        }
        PatientSearchRule rule = patientSearchRuleDAO.get(patientSearchRuleId);
        GetDetailResponse response = new GetDetailResponse();
        if (CommonUtils.isEmpty(rule)) {
            return null;
        }
        //获取详情
        List<PatientSearchRuleDetail> detailList = patientSearchRuleDetailDAO.queryByPatientSearchRuleId(patientSearchRuleId);
        List<PatientSearchRuleDetail> resDetailList = detailList.stream().map((detail) -> {
            if (RuleConditionTypeEnum.OUTPATIENT_DIAGNOSIS.getType() == detail.getRuleConditionType()
                    || RuleConditionTypeEnum.IN_HOSPITAL_DIAGNOSIS.getType() == detail.getRuleConditionType()
                    || RuleConditionTypeEnum.OUT_HOSPITAL_DIAGNOSIS.getType() == detail.getRuleConditionType()) {
                detail.setDiagnosisList(Arrays.asList(detail.getFirstConditionName().split(",")));
            }
            return detail;
        }).collect(Collectors.toList());

        BeanUtils.copyProperties(rule, response);
        response.setRuleDetailList(resDetailList);

        return response;
    }

    @Override
    @RpcService
    @DAOTransaction
    public SaveOrSearchResponse saveOrSearch(SaveOrSearchRequest request) throws ControllerException {
        Long patientSearchRuleId;
        // 是否检索 都要进行保存 先做保存操作
        if (CommonUtils.isNotEmpty(request.getPatientSearchRuleId()) && request.getPatientSearchRuleId() > 0) {
            if (CommonUtils.isNotEmpty(request.getRuleName())) {
                PatientSearchRule byRuleName = patientSearchRuleDAO.getByRuleName(request.getRuleName());
                if (CommonUtils.isNotEmpty(byRuleName) && !byRuleName.getPatientSearchRuleId().equals(request.getPatientSearchRuleId())) {
                    throw new ControllerException("搜索规则名称已存在");
                }
            }
            PatientSearchRule rule = patientSearchRuleDAO.get(request.getPatientSearchRuleId());
            if (CommonUtils.isEmpty(rule)) {
                throw new ControllerException("参数错误");
            }

            if (CommonUtils.isNotEmpty(request.getRuleName())) {
                rule.setRuleName(request.getRuleName());
            }
            //历史检索保存时，需要修改规则类型
//            if (CommonUtils.isNotEmpty(rule.getRuleType()) && rule.getRuleType().equals((byte) 2)) {
//                rule.setRuleType((byte) 1);
//            }
            rule.setLastModifyUserId(request.getUserId());
            rule.setLastModifyTime(new Date());

            patientSearchRuleDAO.update(rule);

            patientSearchRuleId = request.getPatientSearchRuleId();

            // 规则详情这里 删除了 重新加
            patientSearchRuleDetailDAO.deleteDetailByPatientSearchRuleId(patientSearchRuleId);

        } else {
            PatientSearchRule rule = new PatientSearchRule();
            if ("0".equals(request.getSaveOnly())) {
                if (CommonUtils.isEmpty(request.getRuleName())) {
                    // 2 临时(只检索但是没有手动保存的)
                    //只手动查询，不输入规则名称时，按照一下规则进行保存规则名称：[实验室报告：微生物室-凝血酶原时间] AND [XXXX]
                    StringBuffer stringBuffer = new StringBuffer();
                    if (CommonUtils.isNotEmpty(request.getRuleDetailList())) {
                        for (int i = 1; i < request.getRuleDetailList().size(); i++) {
                            stringBuffer.append("[" + RuleConditionTypeEnum.getNameByKey(request.getRuleDetailList().get(i).getRuleConditionType()) + ":");
                            if (request.getRuleDetailList().get(i).getRuleConditionType() == 2) {
                                stringBuffer.append(request.getRuleDetailList().get(i).getFirstKeywordContent() == null ? "" : request.getRuleDetailList().get(i).getFirstKeywordContent());
                            } else {
                                stringBuffer.append(request.getRuleDetailList().get(i).getFirstConditionName() == null ? "" : request.getRuleDetailList().get(i).getFirstConditionName());
                            }
                            if (CommonUtils.isNotEmpty(request.getRuleDetailList().get(i).getSecondConditionName())) {
                                stringBuffer.append("-" + request.getRuleDetailList().get(i).getSecondConditionName());
                            }
                            if (CommonUtils.isNotEmpty(request.getRuleDetailList().get(i).getThirdConditionName())) {
                                stringBuffer.append("-" + request.getRuleDetailList().get(i).getThirdConditionName());
                            }
                            stringBuffer.append("]");
                            //最后一个条件不加AND or规则
                            if (i != request.getRuleDetailList().size() - 1) {
                                stringBuffer.append(request.getRuleDetailList().get(i + 1).getRuleLineType() == 1 ? "AND" : "OR");
                            }
                        }
                        //添加记录时间
                        stringBuffer.append("-[");
                        stringBuffer.append(RuleConditionTypeEnum.getNameByKey(request.getRuleDetailList().get(0).getRuleConditionType()) + ":");
                        stringBuffer.append("[" + DateUtils.toStringForYYYYMMdd(request.getRuleDetailList().get(0).getStartDate()) + "-" + DateUtils.toStringForYYYYMMdd(request.getRuleDetailList().get(0).getEndDate()) + "]]");
                    }
                    rule.setRuleName(stringBuffer.toString());
                    rule.setRuleType((byte) 2);
                    rule.setCreateUserId(request.getUserId());
                    rule.setCreateTime(new Date());
                    rule.setLastModifyTime(new Date());
                    rule.setLastModifyUserId(request.getUserId());
                    rule.setStatus((byte) 1);
                    PatientSearchRule save = patientSearchRuleDAO.save(rule);
                    patientSearchRuleId = save.getPatientSearchRuleId();
                } else {//已经保存了公式，然后通过条件进行查询
                    PatientSearchRule ruleUpdate = patientSearchRuleDAO.get(request.getPatientSearchRuleId());
                    ruleUpdate.setLastModifyUserId(request.getUserId());
                    ruleUpdate.setLastModifyTime(new Date());
                    patientSearchRuleDAO.update(ruleUpdate);
                    patientSearchRuleId = request.getPatientSearchRuleId();
                    // 规则详情这里 删除了 重新加
                    patientSearchRuleDetailDAO.deleteDetailByPatientSearchRuleId(patientSearchRuleId);
                }
            } else {
                if (CommonUtils.isEmpty(request.getRuleName())) {
                    throw new ControllerException("搜索规则名称不能为空");
                }
                if (CommonUtils.isNotEmpty(request.getRuleName())) {
                    PatientSearchRule byRuleName = patientSearchRuleDAO.getByRuleName(request.getRuleName());
                    if (CommonUtils.isNotEmpty(byRuleName)) {
                        throw new ControllerException("搜索规则名称已存在");
                    }
                }
                rule.setRuleName(request.getRuleName());
                rule.setRuleType((byte) 1);
                rule.setCreateUserId(request.getUserId());
                rule.setCreateTime(new Date());
                rule.setLastModifyTime(new Date());
                rule.setLastModifyUserId(request.getUserId());
                rule.setStatus((byte) 1);
                PatientSearchRule save = patientSearchRuleDAO.save(rule);
                patientSearchRuleId = save.getPatientSearchRuleId();
            }
        }
        List<PatientSearchRuleDetail> ruleDetailList = request.getRuleDetailList();
        if (CommonUtils.isNotEmpty(ruleDetailList)) {
            for (PatientSearchRuleDetail patientSearchRuleDetail : ruleDetailList) {
                //TODO 这里需要单独处理 diagnosisList诊断信息进行拼接到firstConditionName上
                if (RuleConditionTypeEnum.OUTPATIENT_DIAGNOSIS.getType() == patientSearchRuleDetail.getRuleConditionType()
                        || RuleConditionTypeEnum.IN_HOSPITAL_DIAGNOSIS.getType() == patientSearchRuleDetail.getRuleConditionType()
                        || RuleConditionTypeEnum.OUT_HOSPITAL_DIAGNOSIS.getType() == patientSearchRuleDetail.getRuleConditionType()) {
                    if (CommonUtils.isNotEmpty(patientSearchRuleDetail.getDiagnosisList())) {
                        patientSearchRuleDetail.setFirstConditionName(patientSearchRuleDetail.getDiagnosisList().stream().collect(Collectors.joining(",")));
                    }
                }
                patientSearchRuleDetail.setPatientSearchRuleId(patientSearchRuleId);
                patientSearchRuleDetailDAO.save(patientSearchRuleDetail);
            }
        }
        SaveOrSearchResponse saveOrSearchResponse = new SaveOrSearchResponse();
        saveOrSearchResponse.setPatientSearchRuleId(patientSearchRuleId);
        if ("0".equals(request.getSaveOnly())) {
            //执行检索
            patientSearchRuleExecuteService.doSearch(patientSearchRuleId);
        }
        return saveOrSearchResponse;
    }


    @Override
    @RpcService
    public List<ListSubscribeResponse> listSubscribe(String userId) throws ControllerException {
        if (CommonUtils.isEmpty(userId)) {
            throw new ControllerException("用户ID不可为空");
        }
        return patientSearchRuleDAO.listSubscribe(userId);
    }

    @Override
    @RpcService
    public void deleteSearchRule(Long patientSearchRuleId) throws ControllerException {
        if (CommonUtils.isEmpty(patientSearchRuleId)) {
            throw new ControllerException("检索规则id不可为空");
        }
        List<PatientSearchRuleSubscribe> byPatientSearchRuleId = patientSearchRuleSubscribeDAO.findByPatientSearchRuleId(patientSearchRuleId);
        BaseResponse baseResponse = new BaseResponse();
        if (CommonUtils.isNotEmpty(byPatientSearchRuleId)) {
            throw new ControllerException("有人订阅 不能删除");
        }
        patientSearchRuleDAO.updateStatus(patientSearchRuleId);
        patientSearchRuleDetailDAO.deleteDetailByPatientSearchRuleId(patientSearchRuleId);
        return;
    }

}
